<template>
  <Paglist
    v-model="apiData"
    :is-init-api="false"
    :parame="parame"
    @register="register"
    :is-show-loadmore="apiData.length > 1"
  >
    <view class="photo-list-container" :style="{ height: containerHeight + 'px' }">
      <template v-for="v in dataList" :key="v.id">
        <view class="photo-list__item" :style="v.styles" @click="previewPhoto(v.url)">
          <TImage
            :src="v.coverUrl"
            :width="v.styles.width"
            :height="v.styles.height"
            mode="aspectFill"
          />
        </view>
      </template>
    </view>
  </Paglist>
</template>

<script setup lang="ts">
  import Paglist from '@/components/Paglist/index.vue';
  import { useConList } from '@/components/Paglist/useConList';
  import { type PhotoListResult } from '@/api/photoAlbum/types';
  import { provide, reactive, ref, watch } from 'vue';
  import { photoList } from '@/api/photoAlbum';
  import { propTypes } from '@/utils/propTypes';
  import TImage from '@/components/TImage/index.vue';

  const props = defineProps({
    belongId: propTypes.number,
    imgWidth: propTypes.number.def(690),
  });

  /** 添加了样式的数据 */
  const dataList = ref<dataItem[]>([]);
  /** 原始数据 */
  const apiData = ref<PhotoListResult[]>([]);

  provide('api', async (obj: any) => {
    const r = await photoList(obj);
    await initData(r.records);
    return r;
  });
  const [register, { refresh }] = useConList();

  interface dataItem extends PhotoListResult {
    imgHeight: number;
    imgWidth: number;
    styles: {
      top: string;
      left: string;
      width: string;
      height: string;
    };
  }

  const parame = reactive({
    belongId: 0,
  });

  watch(
    () => props.belongId,
    (val) => {
      parame.belongId = val;
      getCol();
      refresh?.();
    },
  );

  const { windowWidth } = uni.getWindowInfo();

  /** 间距 */
  const space = ref(15);
  /** 列数 */
  const columns = ref(1);
  /** 图片宽度 */
  const imgWidth = ref(0);
  /** 列高 */
  const allColHeight = ref<number[]>([0]);

  /** 根据图片宽度计算 列数 间隙 */
  function getCol(width?: number) {
    const imgW = uni.upx2px(width || props.imgWidth);
    const col = Math.floor(windowWidth / imgW);
    const sp = (windowWidth - col * imgW) / (col + 1);
    space.value = sp;
    columns.value = col;
    imgWidth.value = imgW;
    allColHeight.value = new Array(col);
    allColHeight.value.fill(0);
  }

  /** 外层容器高度 */
  const containerHeight = ref(500);
  function setContainerHeight() {
    containerHeight.value = Math.max.apply(null, allColHeight.value);
  }

  /** 初始化每页数据 */
  async function initData(val: PhotoListResult[]) {
    for (let index = 0; index < val.length; index++) {
      const v = val[index];
      const { width, height } = await wx.getImageInfo({ src: v.url });
      dataList.value.push({
        ...v,
        imgWidth: width,
        imgHeight: height,
        styles: getStyles(width, height),
      });
    }
    setContainerHeight();
  }

  watch(
    () => props.imgWidth,
    (val) => {
      getCol(val);
      dataList.value.forEach((v) => {
        v.styles = getStyles(v.imgWidth, v.imgHeight);
      });
      setContainerHeight();
    },
  );

  function getStyles(practicalImgWidth: number, practicalImgHeight: number) {
    const nextTops = allColHeight.value;
    const w = imgWidth.value;
    const h = (practicalImgHeight * w) / practicalImgWidth;
    let styles = {
      top: '0px',
      left: '0px',
      width: w + 'px',
      height: h + 'px',
    };
    let minTop = Math.min.apply(null, nextTops);
    styles.top = minTop + space.value + 'px';
    let index = nextTops.indexOf(minTop);
    allColHeight.value[index] += h + space.value;
    let left = (index + 1) * space.value + index * w;
    styles.left = left + 'px';
    return styles;
  }

  /** 预览图片 */
  function previewPhoto(url: string) {
    const urls = dataList.value.map((v) => v.url);
    wx.previewImage({
      urls,
      current: url,
      showmenu: true,
    });
  }

  provide('tabIsShow', false);
</script>

<style lang="scss" scoped>
  .photo-list {
    &-container {
      background-color: #fff;
      position: relative;
      padding-bottom: 30rpx;
    }
    &__content {
      position: relative;
    }
    &__item {
      position: absolute;
      transition: all 0.5s;
      overflow: hidden;
    }
  }
</style>
